package cc.eddic.pratice.programmingparadigms.streampractice.impl;

import cc.eddic.pratice.programmingparadigms.exam.QuestionType;
import cc.eddic.pratice.programmingparadigms.exam.domain.*;
import cc.eddic.pratice.programmingparadigms.exam.impl.QuestionBankServiceCxyImpl;
import cc.eddic.pratice.programmingparadigms.streampractice.QuestionAccuracy;
import cc.eddic.pratice.programmingparadigms.streampractice.QuestionAndAnswer;
import cc.eddic.pratice.programmingparadigms.streampractice.ScoreOfStudentAndCategory;
import cc.eddic.pratice.programmingparadigms.streampractice.StreamPractice;
import lombok.Getter;
import lombok.val;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class StreamPracticeCxyImpl implements StreamPractice {
    @Override
    public List<QuestionAndAnswer> mapToQuestionAndAnswer(List<Question> questionList) {
        Option defaultOption = new Option("default",'*', false);
        return questionList.stream()
                .map(question -> new QuestionAndAnswer(
                        question.getNo(),
                        question.getDescription(),
                        question.getOptions().stream().filter(Option::isCorrectAnswer).findFirst()
                                .orElse(defaultOption).getChoice(),
                        question.getOptions().stream().filter(Option::isCorrectAnswer).findFirst()
                                .orElse(defaultOption).getAnswer()))
                        .collect(Collectors.toList());
    }

    @Getter
    public static class ModelAccuracy {
        public ModelAccuracy(String studentName, int questionNo, String question , char choice ,char correctAnswer) {
            this.studentName = studentName;
            this.questionNo = questionNo;
            this.question = question;
            this.choice = choice;
            this.correctAnswer = correctAnswer;

        }

        public boolean isCorrect() {
            return choice == correctAnswer;
        }

        String studentName;
        int questionNo;
        String question;
        char choice;
        char correctAnswer;
    }



    @Override
    public List<QuestionAccuracy> calculateAccuracy(List<Answer> answerList) {
        List<ModelAccuracy> modelAccuracy = answerList.stream()
                .map(answer -> new ModelAccuracy(answer.getStudent().getName(),
                        answer.getQuestion().getNo(),
                        answer.getQuestion().getDescription(),
                        answer.getChoice(),
                        answer.getQuestion().getOptions().stream()
                                .filter(Option::isCorrectAnswer)
                                .findFirst()
                                .orElse(new Option("", '*', true))
                                .getChoice()))
                .collect(Collectors.toList());
        long studentCount = modelAccuracy.stream().map(ModelAccuracy::getStudentName).distinct().count();
        val questionList = answerList.stream().map(Answer::getQuestion).distinct().collect(Collectors.toList());
        val defaultQuestion = new Question(0, "", QuestionType.SINGLE_CHOICE);

        return modelAccuracy.stream()
                .filter(ModelAccuracy::isCorrect)
                .collect(Collectors.groupingBy(ModelAccuracy::getQuestionNo, Collectors.counting()))
                .entrySet().stream()
                .map(entry -> new QuestionAccuracy(entry.getKey(),
                        questionList.stream().filter(q -> q.getNo() == entry.getKey()).findFirst().orElse(defaultQuestion).getDescription(),
                        entry.getValue().intValue() * 1d / studentCount))
                .sorted((Comparator.comparingDouble(QuestionAccuracy::getAccuracy)))
                .collect(Collectors.toList());

    }


    @Getter
    public static class ModelCatagory {
        public ModelCatagory(String studentName, int questionNo, String question , char choice ,char correctAnswer, String catagory) {
            this.studentName = studentName;
            this.questionNo = questionNo;
            this.question = question;
            this.choice = choice;
            this.correctAnswer = correctAnswer;
            this.catagory = catagory;

        }

        public boolean isCorrect() {
            return choice == correctAnswer;
        }

        String studentName;
        int questionNo;
        String question;
        char choice;
        char correctAnswer;
        String catagory;
    }

    @Override
    public List<ScoreOfStudentAndCategory> calculateScoreOfStudentAndCategory(List<Answer> answerList) {
//        QuestionBankServiceCxyImpl questionBankServiceCxy =new QuestionBankServiceCxyImpl();
//        List<Question> questionList = questionBankServiceCxy.importCategories("q");
//        Category category = new Category("软件开发基础");
//        val basic = new SubCategory("基础");
//        category.add(basic);
//        for (Answer answer : answerList) {
//            questionList.stream().filter(x -> x.getNo() == answer.getQuestion().getNo()).findFirst().ifPresent(q -> answer.getQuestion().setSubCategory(q.getSubCategory().getName().equals("编号") ? basic : q.getSubCategory()));
//        }
//
//        val data = calculateScoreOfStudentAndSubCategory(answerList);
//
//
//        return StreamPractice.super.calculateScoreOfStudentAndCategory(answerList);
        return null;
    }

    @Override
    public List<ScoreOfStudentAndCategory> calculateScoreOfStudentAndSubCategory(List<Answer> answerList) {
        return StreamPractice.super.calculateScoreOfStudentAndSubCategory(answerList);
    }
}
